package cn.fastoo.common.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码工具类
 * 
 * @author LP
 * 
 */
public class ORcodeUtils {

	private static final int FRAME_WIDTH = 2;

	// 二维码写码器
	private static MultiFormatWriter mutiWriter = new MultiFormatWriter();

	/**
	 * 生成二维码图片 png格式
	 * 
	 * @param content
	 *            内容
	 * @param width
	 *            宽 px
	 * @param height
	 *            高 px
	 * @param logofile
	 *            logo图片文件
	 * @param destImagePath
	 *            生成地址
	 */
	public static void encode(String content, int width, int height, File logofile, String destImagePath) {
		try {
			BufferedImage logoImage = ImageIO.read(logofile);
			BufferedImage codeImage = encode(content, width, height, logoImage);
			ImageIO.write(codeImage, "png", new File(destImagePath));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成二维码图片 png格式
	 * 
	 * @param content
	 *            内容
	 * @param width
	 *            宽 px
	 * @param height
	 *            高 px
	 * @param logofile
	 *            logo图片文件
	 * @param destImagePath
	 *            生成地址
	 * @param text
	 *            文字
	 */
	public static void encode(String content, int width, int height, File logofile, String destImagePath, String text) {
		try {
			BufferedImage logoImage = ImageIO.read(logofile);
			BufferedImage codeImage = encode(content, width, height, logoImage);

			int[] imageArray = new int[width * height];
			imageArray = codeImage.getRGB(0, 0, width, height, imageArray, 0, width);
			BufferedImage imageResult = new BufferedImage(width, height + 30, BufferedImage.TYPE_INT_RGB);
			imageResult.setRGB(0, 0, width, height, imageArray, 0, width);

			int[] imageArray2 = new int[width * 30];
			for (int i = 0; i < width * 30; i++) {
				imageArray2[i] = 0xfffffff;
			}
			imageResult.setRGB(0, height, width, 30, imageArray2, 0, width);
			// 设置文字
			Graphics2D g = imageResult.createGraphics();
			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g.setFont(new Font("Tahoma", Font.PLAIN, 24));
			g.setColor(new Color(0, 0, 0));
			g.drawString(text, 10, 440);
			g.dispose();

			ImageIO.write(imageResult, "png", new File(destImagePath));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成二维码图片
	 * 
	 * @param content
	 * @param width
	 * @param height
	 * @param logoImage
	 * @return
	 */
	public static BufferedImage encode(String content, int width, int height, BufferedImage logoImage) {
		try {

			int IMAGE_HALF_WIDTH = logoImage.getWidth() / 2;

			int[][] srcPixels = new int[logoImage.getWidth()][logoImage.getHeight()];
			for (int i = 0; i < logoImage.getWidth(); i++) {
				for (int j = 0; j < logoImage.getHeight(); j++) {
					srcPixels[i][j] = logoImage.getRGB(i, j);
				}
			}

			Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
			hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
			hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
			hint.put(EncodeHintType.MARGIN, 0);
			// 生成二维码
			BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint);

			// 二维矩阵转为一维像素数组
			int halfW = matrix.getWidth() / 2;
			int halfH = matrix.getHeight() / 2;
			int[] pixels = new int[width * height];

			for (int y = 0; y < matrix.getHeight(); y++) {
				for (int x = 0; x < matrix.getWidth(); x++) {
					// 读取图片
					if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH && y > halfH - IMAGE_HALF_WIDTH && y < halfH + IMAGE_HALF_WIDTH) {
						try {
							pixels[y * width + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
						}catch (Exception e){

						}
					}
					// 在图片四周形成边框
					else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH
							+ FRAME_WIDTH)
							|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH
									+ FRAME_WIDTH)
							|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH - IMAGE_HALF_WIDTH
									+ FRAME_WIDTH)
							|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH
									+ FRAME_WIDTH)) {
						pixels[y * width + x] = 0xfffffff;
					} else {
						// 此处可以修改二维码的颜色，可以分别制定二维码和背景的颜色；
						pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff;
					}
				}
			}
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			image.getRaster().setDataElements(0, 0, width, height, pixels);
			return image;
		} catch (WriterException e) {
			e.printStackTrace();
		}
		return null;
	}



	public static BufferedImage encode(String content, int width, int height, BufferedImage logoImage, String text) {
		BufferedImage codeImage = encode(content, width, height, logoImage);
		int[] imageArray = new int[width * height];
		imageArray = codeImage.getRGB(0, 0, width, height, imageArray, 0, width);
		BufferedImage imageResult = new BufferedImage(width, height + 30, BufferedImage.TYPE_INT_RGB);
		imageResult.setRGB(0, 0, width, height, imageArray, 0, width);

		int[] imageArray2 = new int[width * 30];
		for (int i = 0; i < width * 30; i++) {
			imageArray2[i] = 0xfffffff;
		}
		imageResult.setRGB(0, height, width, 30, imageArray2, 0, width);
		// 设置文字
		Graphics2D g = imageResult.createGraphics();
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g.setFont(new Font("宋体", Font.PLAIN, 24));
		g.setColor(new Color(0, 0, 0));
		g.drawString(text, 10, 440);
		g.dispose();
		return imageResult;
	}

	public static BufferedImage encode(String content, int width, int height) {
		try {
			Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
			hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
			hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
			hint.put(EncodeHintType.MARGIN, 0);
			// 生成二维码
			BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint);

			// 二维矩阵转为一维像素数组
			int halfW = matrix.getWidth() / 2;
			int halfH = matrix.getHeight() / 2;
			int[] pixels = new int[width * height];

			for (int y = 0; y < matrix.getHeight(); y++) {
				for (int x = 0; x < matrix.getWidth(); x++) {
						// 此处可以修改二维码的颜色，可以分别制定二维码和背景的颜色；
						pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff;
				}
			}
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			image.getRaster().setDataElements(0, 0, width, height, pixels);
			return image;
		} catch (WriterException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static BufferedImage encode(String content, int width, int height,String logoUrl) {
		return encode(content,width,height,logoUrl,null);
	}

	public static BufferedImage encode(String content, int width, int height, String logoUrl, String text) {
		BufferedImage logo = HttpRequestUtils.getBufferedImageFromUrl(logoUrl);
		if(logo==null){
			return null;
		}
		try {
			if(StringUtils.isBlank(text)){
				return encode(content,width,height,logo);
			}
			return encode(content,width,height,logo,text);
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
}
